package com.hippo.javacore.multithreading;

import java.util.concurrent.ArrayBlockingQueue;

/**
 * @ClassName ThreadDemo14
 * @Description TODO 等待唤醒机制--阻塞队列方式实现
 * @Author tangxl
 * @create 2023-03-14 16:01
 **/
public class ThreadDemo14 {

    //新建一个生产类--厨师
    public static class Cook extends Thread {
        // 定义一个阻塞队列
        ArrayBlockingQueue<String> queue;

        public Cook(ArrayBlockingQueue<String> queue) {
            this.queue = queue;
        }

        @Override
        public void run() {
            while (true) {
                //不断的把面条放入阻塞队列
                try {
                    queue.put("面条");
                    System.out.println("厨师放了一碗面条");
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }

    //定义一个消费类--吃货
    public static class Eater extends Thread {
        // 定义一个阻塞队列
        ArrayBlockingQueue<String> queue;

        public Eater(ArrayBlockingQueue<String> queue) {
            this.queue = queue;
        }
        @Override
        public void run() {
            while (true) {
                //不断的从阻塞队列取面条出来
                try {
                    String cook = queue.take();
                    System.out.println("吃货拿了一碗面条");
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }

    public static void main(String[] args) {
        /**
         * 利用阻塞队列完成生产者与消费者（等待唤醒机制），实现线程轮流交替执行的效果
         * 细节：
         *      生产者和消费者必须使用同一个阻塞队列
         */

        // 创建阻塞队列
        ArrayBlockingQueue<String> queue = new ArrayBlockingQueue<>(1);

        //创建线程,并把阻塞对象传入线程
        Thread cook = new Cook(queue);
        Thread eater = new Eater(queue);

        //线程命名
        cook.setName("厨师");
        eater.setName("吃货");

        //执行线程
        cook.start();
        eater.start();
    }
}
